/**
 ******************************************************************************
 * @文件名称 : task_dataExport.c
 * @摘要 :
 * @创建日期 : Jul 31, 2024
 * @创建者：Mbl
 ******************************************************************************
 * @使用说明
 *
 *
 ******************************************************************************
 */

/* 声明包含头文件 -----------------------------------------------------------*/
#include "../Inc/task_dataExport.h"
#include <stdbool.h>

/* 声明私有类型定义---------------------------------------------------------*/
typedef enum
{
	WRITE_USB_RUN,	// 写运行数据
	WRITE_USB_FUNC	// 写工厂参数
}USB_OPT_Type;

/* 声明私有变量 -------------------------------------------------------------*/
USBH_HandleTypeDef  g_hUSBHost;
static FATFS usbFs;
static FIL usbFile;
/* 声明私有常量 -------------------------------------------------------------*/
static TCHAR *usbPath[] = {
		"1:data.csv",		 		// 存储的曲线路径
		"1:daojin22.bin",    		// 字体路径
		"1:img_start.bin",  	    // 开机图片路径
		"1:img_main.bin",    	    // 主界面图片路径
		"1:img_back.bin",           // 背景图片路径
		"1:img_maininter.bin",      // 主界面内框图片路径
		"1:img_about.bin",          // 关于本机图标
		"1:ico_curve.bin",	        // 曲线图标
		"1:ico_menu.bin",           // 菜单图标
		"1:ico_menuon.bin",	 		// 菜单按钮选中图标
		"1:ico_menuoff.bin",        // 菜单按钮释放图标
		"1:ico_mess.bin",	        // 消息图标
		"1:ico_messon.bin",	        // 消息选中图标
		"1:ico_messoff.bin", 		// 消息未选中图标
		"1:ico_run.bin",            // 运行图标
		"1:ico_stop.bin",	        // 停止图标
		"1:ico_sidebaron.bin",	    // 侧边栏选中图标
		"1:ico_sidebaroff.bin",     // 侧边栏释放图标
		"1:ico_temp.bin",	        // 温度图标
		"1:ico_tempbig.bin",	    // 温度大图标
		"1:ico_toggle.bin",	        // 切换图标
		"1:ico_luck.bin",			// 吉祥物图标
		"1:ico_logo.bin"			// logo图标
};
static const char title[256] = "Datetime, Temp.set(SV), Temp.real(PV), Assist temp.real(PV-1),"
		"Flow set(SV-F), Flow set(PV-F),Outlet Pres.set(SV-P1), Outlet Pres.real(PV-P1), "
		"Liquid return Pres.real(PV-P2)\n";  // excel标题
/* 声明私有宏定义 -----------------------------------------------------------*/
#define USB_Material_CNT     22
/* 声明私有函数 -------------------------------------------------------------*/

/**
  * @brief	检查USB中字库、素材是否存在
  * @param  None
  * @retval TRUE : USB完整   FALSE: 数据不完整
  */
static bool check_USB(void)
{
	FRESULT res;
	FILINFO fno;
	uint8_t paramOkCont = 0;		// 存在参数数量

	for (uint8_t i = 0; i < USB_Material_CNT; i++)		// 循环判断路径是否完整
	{
		res = f_stat(usbPath[i+1], &fno);
		if (res == FR_OK)
		{
			paramOkCont++;
		}
	}
	if (paramOkCont == USB_Material_CNT)
	{
		return true;
	}
	return false;
}
/**
 * @brief  从USB中读取数据
 * @param  path：读路径	 data；读缓冲 size：读大小
 * @retval None
 */
static void fatfs_readUSB(char * path, void * data, uint32_t size)
{
	UINT br;
	FRESULT res;

	res = f_open(&usbFile, path, FA_READ);
	if (res == FR_OK)
	{
		res = f_read(&usbFile, (uint8_t*)data, size, &br);
		f_close(&usbFile);
	}

}
/**
 * @brief  向USB中写入数据
 * @param  type：当前操作类型 path：写路径	 data；写缓冲 cnt：写入的记录条数
 * @retval 无
 */
static void fatfs_writeUSB(USB_OPT_Type type, char * path, void * data, uint32_t cnt)
{
	UINT bw;
	FRESULT res;
	FILINFO fno;

	if (type == WRITE_USB_RUN)		// 写入曲线数据
	{
		if (g_overWritten == 1)		// 导出文件请求
		{
			g_overWritten = 0;
			res = f_unlink(path);
		}
		res = f_stat(path, &fno);
		if (res != FR_OK)           // 文件不存在，创建并添加标题
		{
			res = f_open(&usbFile, path, FA_WRITE | FA_OPEN_ALWAYS);
			if (res == FR_OK)
			{
				res = f_write(&usbFile, title, sizeof(title), &bw);
			}
		}
		else
		{
			res = f_open(&usbFile, path, FA_WRITE | FA_OPEN_APPEND);  // 写指针在最后
		}

		struct chartData* tempChart = (struct chartData*)data;
		/* 写入文件 */
		for (int i = 0; i < cnt; i++)
		{
			f_printf(&usbFile, "20%d-%d-%d %d:%d:%d, %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %.2f\n",
					tempChart[i].chartTime.year,
					tempChart[i].chartTime.month,
					tempChart[i].chartTime.day,
					tempChart[i].chartTime.hour,
					tempChart[i].chartTime.min,
					tempChart[i].chartTime.sec,
					tempChart[i].tempSV,
					tempChart[i].tempPV1,
					tempChart[i].tempPV2,
					tempChart[i].flowSV,
					tempChart[i].flowPV,
					tempChart[i].pressSV,
					tempChart[i].pressPV1,
					tempChart[i].pressPV2
					  );
		}
		f_close(&usbFile);
	}
	else if (type == WRITE_USB_FUNC)
	{
		/* 后期完善 */
	}

}

/**
 * @brief  USB循环检测函数
 * @param  phost：USB结构体 id：USB状态
 * @retval None
 */
void USBH_UserProcess(USBH_HandleTypeDef *phost, uint8_t id)
{
	FRESULT res;
    switch (id)
    {
        case HOST_USER_SELECT_CONFIGURATION:
            break;
        case HOST_USER_DISCONNECTION:
            f_mount(0, "1:", 1);        /* 卸载U盘 */
            break;
        case HOST_USER_CLASS_ACTIVE:
            res = f_mount(&usbFs, "1:", 1);    /* 重新挂载U盘 */
            if (res == FR_OK)
            {
            	g_mountUSB_flag = 1;    // USB挂载成功
            }
            break;
        case HOST_USER_CONNECTION:
            break;
        default:
            break;
    }
}
/**
  * @brief	挂载USB
  * @param  None
  * @retval None
  */
static void mount_USB(void)
{
	uint16_t usbCheckCnt = 0;		// 轮询检查USB次数
    /* USB初始化,后面需要放到外面 */
	USBH_Init(&g_hUSBHost, USBH_UserProcess, HOST_FS);
	USBH_RegisterClass(&g_hUSBHost, USBH_MSC_CLASS);
	USBH_Start(&g_hUSBHost);

	g_mountUSB_flag = 0;						        // 清楚标志位
	while (g_mountUSB_flag != 1 && usbCheckCnt < 1000)  // 检测1000次USB是否插入
	{
		usbCheckCnt++;
		USBH_Process(&g_hUSBHost);
	}

}

/**
  * @brief	读写USB业务逻辑层
  * @param  task 本任务控制结构体
  * @retval None
  */
int bll_dataExport(struct task_pcb *task)
{

	if (task->event & TASK6_EVENT1_USB_MATERIAL_READ)   // 读取素材
	{
		mount_USB();    // 挂载USB

		if (check_USB())
		{
			fatfs_readUSB(usbPath[1], g_fontBuff, sizeof(g_fontBuff)); // 读取字体
			for (uint8_t i = 0; i < 5; i++)
			{
				fatfs_readUSB(usbPath[2 + i], g_imgBuff[i], sizeof(g_imgBuff[i]));   // 读取图标
			}
			for (uint8_t i = 0; i < 16; i++)
			{
				fatfs_readUSB(usbPath[7 + i], g_icoBuff[i], sizeof(g_icoBuff[i]));   // 读取LOGO
			}
			g_RW_State = RW_WRITE_NAND_MATERIAL;
//			g_RW_State = RW_READY;
		}
		else
		{
			g_RW_State = RW_READ_NAND_INIT;
		}
		task->event &= (~TASK6_EVENT1_USB_MATERIAL_READ);
	}

	if (task->event & TASK6_EVENT2_USB_DATA_WRITE)	    // 导出数据
	{
		if (g_mountUSB_flag == 0)  // 防止重复挂载
		{
			mount_USB();    // 挂载USB
		}
		if (g_mountUSB_flag == 1)
		{
			fatfs_writeUSB(WRITE_USB_RUN, usbPath[0], g_packBuff, g_packCount);    // 写入运行数据
			//fatfs_writeUSB(WRITE_USB_RUN, g_packBuff, g_packCount);  // 写入工厂数据
			if (g_packReadOK == 2)
			{
				g_packRW = 0;
				g_packCount = 0;
				g_RW_State = RW_READY;
			}
			else
			{
				g_RW_State = RW_READ_NAND_PACK;
			}
		}
		else
		{
			g_packReadOK = 3;
			g_RW_State = RW_READY;
		}
		task->event &= (~TASK6_EVENT2_USB_DATA_WRITE);
	}
	return 0;
}




